home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 109_01.zip / UCSDIR.C < prev    next >
Text File  |  1993-06-26  |  8KB  |  300 lines

  1. /*    -------------------------------------------------------
  2.     *** Template for Procedure Heading ***
  3.  
  4.     Name:
  5.     Result:
  6.     Errors:
  7.     Globals:
  8.     Macros:
  9.     Procedures:
  10.  
  11.     Action:
  12.  
  13.     ------------------------------------------------------- */
  14.  
  15. /*    : : : : : : : : : : : : : : : : : : : : : : : : : : : :
  16.     ucsdir -- List the  directory of a UCSD Pascal diskette
  17.  
  18.         H.Moran 10/27/79
  19.  
  20.         column labels added 2/13/80
  21.         quick and dirty sort added 2/14/80
  22.  
  23.     : : : : : : : : : : : : : : : : : : : : : : : : : : : : */
  24.  
  25.  
  26.  
  27.  
  28. /*    : : : : : : : : : : : : : : : : : : : : : : : : : : : :
  29.     Constants
  30.     : : : : : : : : : : : : : : : : : : : : : : : : : : : : */
  31.  
  32. #define    SEL_DSK    14        /* bdos function number */
  33. #define    SET_DMA    26        /* bdos function number */
  34.  
  35. #define    SET_TRK    9        /* bios index number */
  36. #define    SET_SEC    10        /* bios index number */
  37. #define    READ    12        /* bios index number */
  38.  
  39. #define    DUMMY    0        /* dummy parameter for bios routine */
  40.  
  41. #define    D_ENT_SZ 26        /* UCSD directory entry size */
  42. #define    D_TITLE    6        /* offset to entry title */
  43. #define    UCSD_NAM_SZ 17        /* size of the name part of ucsd dir entry */
  44. #define UCSD_DIR_SZ 2048    /* size of UCSD directory in bytes */
  45.  
  46. #define    SECT_SIZE 128        /* bytes per physical sector */
  47. #define BLOK_SIZE 512        /* bytes per UCSD logical block */
  48. #define    SECT_PER_BLOK 4        /* physical sectors per logical block */
  49.  
  50.  
  51. /*    : : : : : : : : : : : : : : : : : : : : : : : : : : : :
  52.     Globals    -- these would be static if it were available
  53.     : : : : : : : : : : : : : : : : : : : : : : : : : : : : */
  54.  
  55. int lsn;        /* logical sector number */
  56. int lstlsn;        /* last logical sector number */
  57. int nbytes;        /* number of bytes remaining in ucsd file buffer */
  58. char ucsdbuf[BLOK_SIZE]; /* 1 block buffer for ucsd directory */
  59. char *ptr;        /* pointer to current byte in ucsd buffer */
  60.  
  61. /*    -------------------------------------------------------
  62.  
  63.     Name:        main(argc,argv)
  64.     Result:        ---
  65.     Errors:        ---
  66.     Globals:    lsn,lstlsn,nbytes,ptr,ucsdbuf[]
  67.     Macros:        ---
  68.     Procedures:    printf(),exit(),ucsdir()
  69.  
  70.     Action:        Handle invocation errors
  71.             Call ucsdir() to list from drive B
  72.             a UCSD formatted directory
  73.  
  74.     ------------------------------------------------------- */
  75.  
  76.  
  77. main(argc,argv)
  78.     int argc;
  79.     char *argv[];
  80.     {
  81.  
  82.     lsn = lstlsn = nbytes = 0;    /* init globals */
  83.     ptr = ucsdbuf;
  84.  
  85.     if( argc != 1 )    {
  86.       printf("Proper invocation form is:\n\n");
  87.       printf("ucsdir\n");
  88.       printf("Will list the directory of the UCSD disk on drive B\n");
  89.       exit(1);
  90.       }
  91.     ucsdir();
  92.     exit(0);
  93.     }
  94.  
  95.  
  96.  
  97.  
  98. /*    -------------------------------------------------------
  99.  
  100.     Name:        ucsdir()
  101.     Result:        ---
  102.     Errors:        sector read error (aborts)
  103.     Globals:    lsn,lstlsn
  104.     Macros:        D_TITLE,UCSD_NAM_SZ,UCSD_NAM_SZ
  105.             D_ENT_SZ,SECT_PER_BLOK
  106.     Procedures:    read_ucsd(),putchar(),puts()
  107.  
  108.     Action:        Read from the diskette on drive B
  109.             and print on the console
  110.             the directory of a presumed
  111.             UCSD Pascal formatted disk
  112.  
  113.     ------------------------------------------------------- */
  114.  
  115.  
  116. ucsdir()
  117.     {
  118.     char ucsd_dir[UCSD_DIR_SZ];
  119.     char *dir,*saved_dir;
  120.     int name_len,colct,entries,dunno;
  121.     int cmpare(),i;
  122.  
  123.     read_ucsd(ucsd_dir,(2*SECT_PER_BLOK),4); /* get entire directory */
  124.  
  125.     dir = &ucsd_dir[D_TITLE];        /* print volume label */
  126.     puts("\nDirectory of : ");
  127.     name_len  = *dir++;
  128.     while ( name_len-- )
  129.       putchar(*dir++);
  130.     puts("\n\n");
  131.  
  132.     dir = &ucsd_dir[(D_TITLE + D_ENT_SZ)];    /* point to 1'st entry */
  133.     i = 0;
  134.     while( *(dir+i) != 0 && (dir+i) < &ucsd_dir[UCSD_DIR_SZ] )
  135.      i += D_ENT_SZ;
  136.     qsort((dir-D_TITLE),(i)/D_ENT_SZ,D_ENT_SZ,&cmpare);
  137.     entries = 0;
  138.     puts("\nFilename         locn len  type");
  139.     puts("  Filename         locn len  type");
  140.     puts("\n---------------- ---- ---- ----");
  141.     puts("  ---------------- ---- ---- ----\n");
  142.     while ( dir < &ucsd_dir[UCSD_DIR_SZ] ) {/* print directory entries */
  143.       saved_dir = dir;
  144.       colct = 1;
  145.       name_len = *dir++;
  146.       if( name_len <= 0 || name_len > (UCSD_NAM_SZ-1) )
  147.         break;
  148.       while( name_len-- ) {        /* print the file name */
  149.         putchar(*dir++);
  150.         colct++;
  151.         }
  152.       while( colct++ <UCSD_NAM_SZ )    /* print spaces to max name length */
  153.         putchar(' ');
  154.  
  155.       dir = saved_dir - D_TITLE;    /* point to begin of entry */
  156.                     /* i.e. block alloc. indicators */
  157.  
  158.       lsn = *dir++ + ( *dir++ << 8);/* lsn = starting logical block # */
  159.       lstlsn= *dir++ +(*dir++ << 8);/* lstlsn = ending logical block # */
  160.       dunno = *dir++ + (*dir++ <<8);/* file type */
  161.  
  162.  
  163.       printf(" %4d %4d %4d",lsn,lstlsn-lsn,dunno);
  164.       dir = saved_dir + D_ENT_SZ;    /* dir = pointer to next entry */
  165.       entries & 1 ? puts("\n") : puts("  ");
  166.       entries++;
  167.       }
  168.     return;
  169.     }
  170.  
  171. /*    -------------------------------------------------------
  172.  
  173.     Name:        read_ucsd(buf,rn,count)
  174.     Result:        result of selecting drive A
  175.     Errors:        sector read error (exit to CP/M)
  176.     Globals:    ---
  177.     Macros:        SEL_DSK,SET_DMA,SET_TRK,SET_SEC
  178.             READ,DUMMY,SECT_SIZE,SEL_DSK
  179.  
  180.     Procedures:    bdos(),bios(),printf(),exit()
  181.             track(),sector()
  182.  
  183.     Action:        Read count UCSD sized blocks from drive B
  184.             into buf[] starting at logical record number
  185.             rn using the UCSD Pascal logical record
  186.             number to physical sector mapping
  187.  
  188.     ------------------------------------------------------- */
  189.  
  190.  
  191. read_ucsd(buf,rn,count)
  192.     char *buf;
  193.     int rn;
  194.     int count;
  195.     {
  196.     char bios();
  197.     int seccnt; seccnt = count*4;
  198.  
  199.     bdos(SEL_DSK,1);
  200.     while( seccnt-- ) {
  201.       bdos(SET_DMA,buf);
  202.       bios(SET_TRK,track(rn));
  203.       bios(SET_SEC,sector(rn));
  204.       if( bios(READ,DUMMY) ) {
  205.         printf("read error @ track %2d sector %2d",track(rn),sector(rn));
  206.         exit(1);
  207.         }
  208.       buf += SECT_SIZE;
  209.       rn++;
  210.       }
  211.     return bdos(SEL_DSK,0);
  212.     }
  213.  
  214. /*    -------------------------------------------------------
  215.  
  216.     Name:        sector(rn)
  217.     Result:        physical sector number
  218.     Errors:        ---
  219.     Globals:    ---
  220.     Macros:        ---
  221.     Procedures:    ---
  222.  
  223.     Action:        This code maps logical sectors to physical
  224.             sectors    by selecting every second sector
  225.             in order (accounting for the modulo 26
  226.             process) on the diskette except    that at a
  227.             track switchover point there is an additional
  228.             'gap' of 6 sectors (total of 7) to allow
  229.             for the drive to seek. This is UCSD's
  230.             attempt to minimize disk access    time.
  231.  
  232.     ------------------------------------------------------- */
  233.  
  234.  
  235. sector(rn)
  236.     unsigned rn;
  237.     {
  238.     unsigned t1,t2,trk,t3,sect;
  239.  
  240.     t1 = rn % 26;
  241.     t2 = t1 << 1;
  242.     if(t1 > 12)
  243.       t2++;
  244.     trk = rn/26;        /* zero based absolute track */
  245.     t3 = t2 + 6*trk;    /* new logical sector number */
  246.     sect = t3 % 26;        /* new zero based absolute sector */
  247.     return ++sect;        /* one based absolute sector */
  248.     }
  249.  
  250. /*    -------------------------------------------------------
  251.  
  252.     Name:        track(rn)
  253.     Result:        physical track number
  254.     Errors:        ---
  255.     Globals:    ---
  256.     Macros:        ---
  257.     Procedures:    ---
  258.  
  259.     Action:        convert logical sector number to
  260.             absolute track number. This is simply
  261.             the modulo 26 process except that
  262.             track 0 is not considered part of the
  263.             logical sector space.
  264.  
  265.     ------------------------------------------------------- */
  266.  
  267.  
  268. track(rn)
  269.     unsigned rn;
  270.     {
  271.     return rn/26 + 1;
  272.     }
  273.  
  274.  
  275. /* tacked on compare of filenames */
  276.  
  277.  
  278. cmpare(x,y)
  279.     char *x,*y;
  280.     {
  281.     int i,j,k;
  282.  
  283.     x += D_TITLE;
  284.     y += D_TITLE;
  285.     for( i = *x++, j = *y++; j & i; i--, j--, x++, y++ ) {
  286.       if( *x > *y )
  287.         return -1;
  288.       if( *x < *y )
  289.         return 1;
  290.       }
  291.     if( i && ! j )
  292.       return 1;
  293.     if( j && ! i )
  294.       return -1;
  295.     return 0;
  296.     }
  297.  
  298.  
  299.  
  300.